package com.guigu.qingcheng.service.impl;

import com.github.wxpay.sdk.Config;
import com.github.wxpay.sdk.WXPayRequest;
import com.github.wxpay.sdk.WXPayUtil;
import com.guigu.qingcheng.client.GoodsClient;
import com.guigu.qingcheng.mapper.TbOrderItemMapper;
import com.guigu.qingcheng.mapper.TbOrderLogMapper;
import com.guigu.qingcheng.pojo.TbOrder;
import com.guigu.qingcheng.pojo.TbOrderItem;
import com.guigu.qingcheng.pojo.TbOrderLog;
import com.guigu.qingcheng.pojo.vo.CloseOrderVo;
import com.guigu.qingcheng.service.TbOrderItemService;
import com.guigu.qingcheng.service.TbOrderService;
import com.guigu.qingcheng.service.WxPayService;
import com.guigu.qingcheng.utils.IdWorker;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class WxPayServiceImpl implements WxPayService {

    @Autowired(required = false)
    private Config config;

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private TbOrderService tbOrderService;

    @Autowired(required = false)
    private TbOrderLogMapper tbOrderLogMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private TbOrderItemService tbOrderItemService;

    @Autowired
    private GoodsClient goodsClient;

    public  void addLog(TbOrder order, String beizhu){
        // 记录订单日志
        TbOrderLog log=new TbOrderLog();
        log.setId(idWorker.nextId()+""); // id
        log.setOperater("system"); // 操作员 暂时设为系统
        log.setOperateTime(new Date()); // 操作时间
        log.setOrderId(order.getId()); // 订单id
        log.setOrderStatus(order.getOrderStatus()); // 订单状态
        log.setPayStatus(order.getPayStatus()); // 付款状态
        log.setConsignStatus(order.getConsignStatus()); // 发货状态
        log.setRemarks(beizhu); // 备注
        tbOrderLogMapper.insertSelective(log);
    }

    @Override
    public Map createNative(String orderId, Integer money, String notifyUrl) {

        try {
            // 封装请求参数
            Map<String,String> map=new HashMap();
            map.put("appid",config.getAppID()); //公众号ID
            map.put("mch_id",config.getMchID()); // 商户号
            map.put("nonce_str", WXPayUtil.generateNonceStr());// 随机字符串
            map.put("body","青橙");// 商品描述
            map.put("out_trade_no",orderId);// 订单号
            map.put("total_fee","1"); //只能支付一分钱
           // map.put("total_fee",money+"");//金额
            map.put("spbill_create_ip","127.0.0.1");// ip
            map.put("notify_url",notifyUrl);//回调地址
            map.put("trade_type","NATIVE");//交易类型

            String xmlParam = null; //返回xml格式的参数
            xmlParam = WXPayUtil.generateSignedXml(map, config.getKey());
            // 发送请求
            WXPayRequest wxPayRequest=new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/unifiedorder", null, xmlParam, false);
            // 解析返回结果

            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            Map m=new HashMap();
            m.put("code_url",mapResult.get("code_url"));
            m.put("total_fee",money+"");
            m.put("out_trade_no",orderId);
            return m;
        } catch (Exception e) {
            e.printStackTrace();
            return new HashMap();
        }
    }

    @Override
    public void notifyLogic(String xml) {
        try {
            // 把xml转成map
            Map<String, String> map = WXPayUtil.xmlToMap(xml);

            // 验证签名
            boolean signatureValid = WXPayUtil.isSignatureValid(map, config.getKey());

            TbOrder order = tbOrderService.findById(map.get("out_trade_no"));

            // 检查签名是否合法
            if(signatureValid){
                if("SUCCESS".equals(map.get("result_code"))){
                    //修改订单状态
                    tbOrderService.updatePayStatus(map.get("out_trade_no"),map.get("transaction_id"));
                    //发送订单号给mq
                    amqpTemplate.convertAndSend("paynotify","",map.get("out_trade_no"));
                }else {
                    // 支付失败
                    addLog(order,"支付失败:"+order.getId());
                }
            }else {
                // 记录日志
                addLog(order,"非法支付操作:"+order.getId());
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }



    @Override
    public void selectOrder(String orderId) {

        try {
            // 封装请求参数
            Map<String,String> map=new HashMap();
            map.put("appid",config.getAppID()); //公众号ID
            map.put("mch_id",config.getMchID()); // 商户号
            map.put("nonce_str", WXPayUtil.generateNonceStr());// 随机字符串
            map.put("out_trade_no",orderId);// 订单号
            String xmlParam = null; //返回xml格式的参数
            xmlParam = WXPayUtil.generateSignedXml(map, config.getKey());
            WXPayRequest wxPayRequest=new WXPayRequest(config);
            String xmlResult = wxPayRequest.requestWithCert("/pay/orderquery", null, xmlParam, false);
            // 解析返回结果

            Map<String, String> mapResult = WXPayUtil.xmlToMap(xmlResult);
            if("SUCCESS".equals(mapResult.get("return_code"))){
                if("SUCCESS".equals(mapResult.get("trade_state"))){
                    // 微信平台支付成功
                    // 修改订单状态
                    tbOrderService.updatePayStatus(orderId,mapResult.get("transaction_id"));

                }else {
                    // 微信平台支付失败
                    // 关闭微信订单
                    map.put("nonce_str", WXPayUtil.generateNonceStr());// 随机字符串
                    xmlParam = WXPayUtil.generateSignedXml(map, config.getKey());
                    WXPayRequest wxPayRequest2=new WXPayRequest(config);
                    String xmlResult2 = wxPayRequest2.requestWithCert("/pay/closeorder", null, xmlParam, false);

                    // 修改订单状态 已关闭
                    CloseOrderVo closeOrderVo = new CloseOrderVo();
                    closeOrderVo.setId(orderId);
                    tbOrderService.closeOrder(closeOrderVo);
                    //修改库存
                    List<TbOrderItem> orderItem = tbOrderItemService.getOrderItem(orderId);
                    goodsClient.deductionStock2(orderItem);
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        }


    }
}
